#include "Tile.h"
//#include "TileManager.h"
//class TileManager;
#include "TileManager.h"
#include "BaseCharacter.h"
#include "SGD Wrappers\CSGD_TextureManager.h"
#include "Game.h"
#include "GamePlayState.h"

Tile::Tile(void)
{
	highlighted = false;
	r = 255;
	g = 255;
	b = 255;
	a = 255;
}


Tile::~Tile(void)
{
}

void Tile::ApplyEffect()
{
	if(this->character == nullptr)
		return;

	switch(this->terrainType)
	{
	case SNOW:
		{
			bool alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == MOVEMENT)
					alreadyThere = true;
			}

			if(alreadyThere)
				break;

			StatusEffect * effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = MOVEMENT;
			effect->effectValue = -1;
			effect->turnsLeft = -1;

			this->character->SetMov(character->GetMov()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);

			break;
		}
	case MUD:
		{
			bool alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == ATTACK)
					alreadyThere = true;
			}
			StatusEffect * effect = nullptr;
			if(!alreadyThere)
			{

				effect = new StatusEffect();
				effect->creator = nullptr;
				effect->effectType = ATTACK;
				effect->effectValue = -character->GetAtk()/4;
				effect->turnsLeft = -1;

				this->character->SetAtk(character->GetAtk()+effect->effectValue);
				this->character->GetTileEffects()->push_back(effect);
			}
			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == DEFENSE)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
				effect = new StatusEffect();
				effect->creator = nullptr;
				effect->effectType = DEFENSE;
				effect->effectValue = -character->GetDef()/4;
				effect->turnsLeft = -1;

				this->character->SetDef(character->GetDef()+effect->effectValue);
				this->character->GetTileEffects()->push_back(effect);
			}
			break;
		}
	case WATER:
		{
			bool alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == MOVEMENT)
					alreadyThere = true;
			}

			if(alreadyThere)
				break;

			StatusEffect * effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = MOVEMENT;
			effect->effectValue = -1;
			effect->turnsLeft = -1;

			this->character->SetMov(character->GetMov()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);
			break;
		}
	case SHRUB:
		{
			bool alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == DEFENSE)
					alreadyThere = true;
			}

			if(alreadyThere)
				break;

			StatusEffect * effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = DEFENSE;
			effect->effectValue = this->GetCharacter()->GetDef()/4;
			effect->turnsLeft = -1;

			this->character->SetDef(character->GetDef()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);
			break;
		}
	case LAVA:
		{
			bool alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == DEFENSE)
					alreadyThere = true;
			}
			StatusEffect * effect = nullptr;
			if(!alreadyThere)
			{
				
				effect = new StatusEffect();
				effect->creator = nullptr;
				effect->effectType = DEFENSE;
				effect->effectValue = -this->GetCharacter()->GetDef()/2;
				effect->turnsLeft = -1;

				this->character->SetDef(character->GetDef()+effect->effectValue);
				this->character->GetTileEffects()->push_back(effect);
			}

			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == ATTACK)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
			effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = ATTACK;
			effect->effectValue = -this->GetCharacter()->GetAtk()/2;
			effect->turnsLeft = -1;

			this->character->SetAtk(character->GetAtk()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);
			}
			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == SPEED)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
			effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = SPEED;
			effect->effectValue = -this->GetCharacter()->GetSpd()/2;
			effect->turnsLeft = -1;

			this->character->SetSpd(character->GetSpd()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);
			}
			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == AGILITY)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
			effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = AGILITY;
			effect->effectValue = -this->GetCharacter()->GetAgi()/2;
			effect->turnsLeft = -1;

			this->character->SetAgi(character->GetAgi()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);
			}
			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == MOVEMENT)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
			effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = MOVEMENT;
			effect->effectValue = -1;
			effect->turnsLeft = -1;

			this->character->SetMov(character->GetMov()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);
			}
			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == RANGE)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
			if(this->GetCharacter()->GetRng())
			{
				effect = new StatusEffect();
				effect->creator = nullptr;
				effect->effectType = RANGE;
				effect->effectValue = -this->GetCharacter()->GetRng()/2;
				effect->turnsLeft = -1;

				this->character->SetRng(character->GetRng()+effect->effectValue);
				this->character->GetTileEffects()->push_back(effect);
			}
			}
			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == STAMINA)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
			effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = STAMINA;
			effect->effectValue = -this->GetCharacter()->GetSta()/2;
			effect->turnsLeft = -1;

			this->character->SetSta(character->GetSta()+effect->effectValue);
			this->character->GetTileEffects()->push_back(effect);
			}
			alreadyThere = false;
			for(unsigned int i = 0; i < character->GetTileEffects()->size();i++)
			{
				if((*character->GetTileEffects())[i]->effectType == LAVA_DAMAGE)
					alreadyThere = true;
			}
			if(!alreadyThere)
			{
			effect = new StatusEffect();
			effect->creator = nullptr;
			effect->effectType = LAVA_DAMAGE;
			effect->effectValue = 2;
			effect->turnsLeft = -1;

			this->character->GetTileEffects()->push_back(effect);
			}
			break;
		}
	};
}

void Tile::RemoveEffect()
{
	if(this->character == nullptr)
		return;


	for(unsigned int i = 0; i < this->GetCharacter()->GetTileEffects()->size();i++)
	{
		switch((*GetCharacter()->GetTileEffects())[i]->effectType)
		{
		case MOVEMENT:
			{
				GetCharacter()->SetMov(GetCharacter()->GetMov()-(*GetCharacter()->GetTileEffects())[i]->effectValue);
				break;
			}
		case DEFENSE:
			{
				GetCharacter()->SetDef(GetCharacter()->GetDef()-(*GetCharacter()->GetTileEffects())[i]->effectValue);
				break;
			}
		case ATTACK:
			{
				GetCharacter()->SetAtk(GetCharacter()->GetAtk()-(*GetCharacter()->GetTileEffects())[i]->effectValue);
				break;
			}
		case RANGE:
			{
				GetCharacter()->SetRng(GetCharacter()->GetRng()-(*GetCharacter()->GetTileEffects())[i]->effectValue);
				break;
			}
		case SPEED:
			{
				GetCharacter()->SetSpd(GetCharacter()->GetSpd()-(*GetCharacter()->GetTileEffects())[i]->effectValue);
				break;
			}
		case AGILITY:
			{
				GetCharacter()->SetAgi(GetCharacter()->GetAgi()-(*GetCharacter()->GetTileEffects())[i]->effectValue);
				break;
			}
		case STAMINA:
			{
				GetCharacter()->SetSta(GetCharacter()->GetSta()-(*GetCharacter()->GetTileEffects())[i]->effectValue);
				break;
			}
		};
	}
	
	while(GetCharacter()->GetTileEffects()->size() >0)
	{
		delete (*GetCharacter()->GetTileEffects())[0];
		(*GetCharacter()->GetTileEffects()).erase((*GetCharacter()->GetTileEffects()).begin());
	}

	GetCharacter()->GetTileEffects()->clear();
	return;

}

void Tile::Render()
{
	TileManager * tm = TileManager::GetInstance();
	RECT rect;
	rect.left = (LONG)((this->x * tm->GetTileSizeX() * tm->GetScale()) + tm->GetPosX()* tm->GetScale());
	rect.right = (LONG)(rect.left + tm->GetTileSizeX() * tm->GetScale());
	rect.top = (LONG)((this->y * tm->GetTileSizeY()* tm->GetScale())+tm->GetPosY()* tm->GetScale());
	rect.bottom = (LONG)(rect.top + tm->GetTileSizeY() * tm->GetScale());


	if(rect.bottom < 0 || rect.top > Game::GetInstance()->GetWinHeight() || rect.left > Game::GetInstance()->GetWinWidth() || rect.right < 0)
		return;

	CSGD_TextureManager * texm = CSGD_TextureManager::GetInstance();

	texm->Draw(tm->GetTileBmpID(),rect.left,rect.top,tm->GetScale(),tm->GetScale(),&tm->CreateTileSourceRect(this->imageID),0.0f,0.0f,0.0f,D3DCOLOR_XRGB(255,255,255));
		
	if(highlighted)
	{
		//CSGD_Direct3D::GetInstance()->GetSprite()->Flush();

		RECT tempR;
		tempR.left = 0;
		tempR.right = 64;
		tempR.bottom = 64;
		tempR.top = 0;

		texm->Draw(Game::GetInstance()->GetBlankRect(),rect.left,rect.top,tm->GetScale(),tm->GetScale(),&tempR,0.0f,0.0f,0.0f,D3DCOLOR_ARGB(a,r,g,b));
	}

	if(this->character != nullptr)
		this->character->Render();

}

void Tile::Update(float elapsedTime)
{
	if(this->GetCharacter()!= nullptr && !this->highlighted)
	{
		if(this->GetCharacter()->IsPlayer())
		{
			this->HighlightTile(true,0,255,255,90);
		}
	}
}

int Tile::GetScreenPosX()
{
	return (this->x * TileManager::GetInstance()->GetTileSizeX()) + TileManager::GetInstance()->GetPosX();
}

int Tile::GetScreenPosY()
{
	return (this->y * TileManager::GetInstance()->GetTileSizeY())+TileManager::GetInstance()->GetPosY();
}

void Tile::ChangeTileType(int type)
{
	if(this->terrainType == type)
		return;

	switch (type)
	{
	case GRASS:
		{
			this->terrainType = GRASS;
			this->obstacle = false;
			this->imageID = 0;
			break;
		}
	case DIRT:
		{
			this->terrainType = DIRT;
			this->obstacle = false;
			this->imageID = 1;
			break;
		}
	case STONE_FLOOR:
		{
			this->terrainType = STONE_FLOOR;
			this->obstacle = false;
			this->imageID = 2;
			break;
		}
	case STONE_WALL:
		{
			this->terrainType = STONE_WALL;
			this->obstacle = true;
			this->imageID = 3;
			break;
		}
	case TREE:
		{
			this->terrainType = TREE;
			this->obstacle = true;
			this->imageID = 4;
			break;
		}
	case WATER:
		{
			this->terrainType = WATER;
			this->obstacle = false;
			this->imageID = 5;
			break;
		}
	case MUD:
		{
			this->terrainType = MUD;
			this->obstacle = false;
			this->imageID = 6;
			break;
		}
	case LAVA:
		{
			this->terrainType = LAVA;
			this->obstacle = false;
			this->imageID = 7;
			break;
		}
	case ROCKS:
		{
			this->terrainType = ROCKS;
			this->obstacle = true;
			this->imageID = 8;
			break;
		}
	case MOUNTIAN:
		{
			this->terrainType = MOUNTIAN;
			this->obstacle = true;
			this->imageID = 9;
			break;
		}
	case SNOW:
		{
			this->terrainType = SNOW;
			this->obstacle = false;
			this->imageID = 10;
			break;
		}
	case SHRUB:
		{
			this->terrainType = SHRUB;
			this->obstacle = false;
			this->imageID = 11;
			break;
		}
	case PILLAR:
		{
			this->terrainType = PILLAR;
			this->obstacle = true;
			this->imageID = 12;
			break;
		}
	case CROWD:
		{
			this->terrainType = CROWD;
			this->obstacle = true;
			this->imageID = 13;
			break;
		}
	}



}

void Tile::HighlightTile(bool on, int red,int green,int blue, int alpha)
{
	highlighted = on;
	r = red;
	g = green;
	b = blue;
	a = alpha;
}
